package org.amphiprion.kidcalendar.dao.xml;

import java.util.ArrayList;
import java.util.List;

import org.amphiprion.kidcalendar.entity.Configuration;
import org.amphiprion.kidcalendar.entity.DateRule;
import org.amphiprion.kidcalendar.entity.Rule;
import org.amphiprion.kidcalendar.entity.Vacation;
import org.amphiprion.kidcalendar.entity.VacationCalendar;
import org.amphiprion.kidcalendar.entity.VacationRule;
import org.amphiprion.kidcalendar.entity.function.Function;
import org.amphiprion.kidcalendar.entity.function.Input;
import org.amphiprion.kidcalendar.entity.function.Output;
import org.amphiprion.whohavethekids.R;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xmlpull.v1.XmlPullParser;

import android.content.Context;
import android.content.res.XmlResourceParser;

public class FunctionDao extends AbstractXmlDao {
	private static FunctionDao instance;

	private Context context;

	public static FunctionDao getInstance(Context context) {
		if (instance == null) {
			instance = new FunctionDao(context);
		}
		return instance;
	}

	public FunctionDao(Context context) {
		this.context = context;
	}

	public List<Function> getFunctions() {
		try {
			XmlResourceParser xpp = context.getResources().getXml(R.xml.functions);

			ArrayList<Function> functions = new ArrayList<Function>();
			Function current = null;
			int eventType = xpp.getEventType();
			while (eventType != XmlPullParser.END_DOCUMENT) {
				if (eventType == XmlPullParser.START_DOCUMENT) {
					// System.out.println("Start document");
				} else if (eventType == XmlPullParser.START_TAG) {
					if ("function".equals(xpp.getName())) {
						current = new Function();
						for (int i = 0; i < xpp.getAttributeCount(); i++) {
							String attrName = xpp.getAttributeName(i);
							if ("name".equals(attrName)) {
								current.setName(context.getString(xpp.getAttributeResourceValue(i, 0)));
							} else if ("class".equals(attrName)) {
								current.setClassName(xpp.getAttributeValue(i));
							} else if ("method".equals(attrName)) {
								current.setMethodName(xpp.getAttributeValue(i));
							}
						}
						functions.add(current);
					} else if ("input".equals(xpp.getName())) {
						Input input = new Input();
						for (int i = 0; i < xpp.getAttributeCount(); i++) {
							String attrName = xpp.getAttributeName(i);
							if ("name".equals(attrName)) {
								input.setName(context.getString(xpp.getAttributeResourceValue(i, 0)));
							} else if ("class".equals(attrName)) {
								input.setClassName(xpp.getAttributeValue(i));
							} else if ("hideTitle".equals(attrName)) {
								input.setHideTitle("true".equals(xpp.getAttributeValue(i)));
							}
						}
						current.getInputs().add(input);
					} else if ("output".equals(xpp.getName())) {
						Output output = new Output();
						for (int i = 0; i < xpp.getAttributeCount(); i++) {
							String attrName = xpp.getAttributeName(i);
							if ("name".equals(attrName)) {
								output.setName(context.getString(xpp.getAttributeResourceValue(i, 0)));
							} else if ("type".equals(attrName)) {
								output.setType(xpp.getAttributeValue(i));
							} else if ("class".equals(attrName)) {
								output.setClassName(xpp.getAttributeValue(i));
							}
						}
						current.setOutput(output);
					}
				} else if (eventType == XmlPullParser.END_TAG) {
					// System.out.println("End tag " + xpp.getName());
				} else if (eventType == XmlPullParser.TEXT) {
					// System.out.println("Text " + xpp.getText());
				} else if (eventType == XmlPullParser.TEXT) {
					//
				}
				eventType = xpp.next();
			}

			return functions;
		} catch (Throwable e) {
			e.printStackTrace();
			// Log.e(ApplicationConstants.PACKAGE, "", e);
			return null;
		}

	}

	private void collectVacation(Element vacationCalendarNode, VacationCalendar vc) {
		NodeList list = vacationCalendarNode.getElementsByTagName("vacation");
		for (int i = 0; i < list.getLength(); i++) {
			Element node = (Element) list.item(i);
			Vacation v = new Vacation();
			v.setName(getAttribute(node, "name", ""));
			v.setFrom(getAttribute(node, "from", ""));
			v.setTo(getAttribute(node, "to", ""));
			vc.getVacations().add(v);
		}
	}

	private void collectRules(Configuration configuration, Element parentNode, List<Rule> rules) {
		NodeList childNodes = parentNode.getChildNodes();
		for (int i = 0; i < childNodes.getLength(); i++) {
			Node node = childNodes.item(i);
			if (node.getNodeName().equals("date-rule")) {
				Element dateRuleNode = (Element) node;
				DateRule dr = new DateRule();
				dr.setType(getAttribute(dateRuleNode, "type", ""));
				dr.setValue(getAttribute(dateRuleNode, "value", ""));
				dr.setStart(getAttribute(dateRuleNode, "start", ""));
				rules.add(dr);
				collectRules(configuration, dateRuleNode, dr.getSubRules());
			} else if (node.getNodeName().equals("vacation-rule")) {
				Element vacationRuleNode = (Element) node;
				VacationRule vr = new VacationRule();
				vr.setType(getAttribute(vacationRuleNode, "type", ""));
				vr.setVacationCalendar(configuration.getVacationCalendar(getAttribute(vacationRuleNode, "vacation-calendar-id", "")));
				rules.add(vr);
				collectRules(configuration, vacationRuleNode, vr.getSubRules());
			}
		}
	}
}
